const Store = require("electron-store");
const http = require("http");
const fs = require("fs");
const store = new Store();
import { getProjectPath } from "./render";
import { fileType } from "./html/util";
import { removeCssComment } from "./html/cssAnalyser";
import { upload } from "./api/upload";

const hostname = "127.0.0.1";
const port = 8080;

export const runServer = () =>
  server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
    store.set({
      serverUrl: `http://${hostname}:${port}/`,
    });
  });

export const closeServer = () => {
  console.log("close server");
  rawStructure = {
    html: [],
    js: [],
    css: [],
    img: [],
  };
  folderTree = [];
  server.close();
};

export interface fileStructureInterface {
  html: string[];
  js: string[];
  css: string[];
  img: string[];
}
export interface duplication {
  type: "js" | "css" | "img" | "html";
  relativePath: string;
  newName: string;
  name: string;
}
// let structure: fileStructureInterface = {
//   html: [],
//   js: [],
//   css: [],
//   img: [],
// };
export let rawStructure: fileStructureInterface = {
  html: [],
  js: [],
  css: [],
  img: [],
};

// let duplicate: duplication[] = [];
export type folderTreeType = {
  id: number;
  originalFilename: string;
  fileName: string;
  duplicate: boolean;
  dest: string;
};
export let folderTree: folderTreeType[] = [];

export const appendIdAndMove = (
  filePath: string,
  id: number | string,
  destPath: string
): void => {
  let file = fs.readFileSync(filePath);
  // add comment to id
  switch (fileType(destPath)) {
    case "js":
      id = "/*" + id + "*/";
      break;
    case "css":
    case "less":
      file = Buffer.from(removeCssComment(file.toString())); // remove normal comment
      id = "/*" + id + "*/";
      break;
    case "htm":
    case "html":
      id = "<!--" + id + "-->";
      break;
  }
  // add comment
  let idBuffer = Buffer.allocUnsafe(10);
  let idTmp = Buffer.from(id + "");

  idTmp.copy(idBuffer, 0, 0, idTmp.length);
  const data = Buffer.allocUnsafe(file.length + 10);
  file.copy(data, 0, 0, file.length);
  idBuffer.copy(data, file.length, 0, idBuffer.length);
  fs.writeFileSync(destPath, data);
  fs.unlinkSync(filePath);
};

// fileContent: string
export const gainIdFromFile = (
  filePath: string,
  fileBuffer: Buffer
): string => {
  let id: Buffer = Buffer.allocUnsafe(10);
  // const file = fs.readFileSync(filePath);
  fileBuffer.copy(id, 0, fileBuffer.length - 10, fileBuffer.length);
  // remove redundant zero
  let i = 9;
  for (; i >= -1 && id[i] === 0; i--);
  i++;
  id = id.slice(0, i);
  let idStr = id.toString();
  // remove comment
  switch (fileType(filePath)) {
    case "js":
    // idStr = idStr.replace(/(\/|\*)/g, "");
    // break;
    case "css":
    case "less":
      idStr = idStr.replace(/(\/|\*)/g, "");
      break;
    case "htm":
    case "html":
      idStr = idStr.replace(/(<!--|-->)/g, "");
      break;
  }
  // remove comment
  return idStr;
};

export const removeIdFromFile = (filePath: string): void => {
  const file = fs.readFileSync(filePath);
  //debug
  // if (filePath.endsWith(".html")) {
  //   console.log(file.toString());
  // }
  //debug
  const len = file.length - 10;
  const res = Buffer.allocUnsafe(len);
  file.copy(res, 0, 0, len);
  fs.writeFileSync(filePath, res);
};

const server = http.createServer((req, res) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Headers", "*");
  res.setHeader("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
  res.statusCode = 200;

  if (req.method.toLowerCase() === "options") {
    res.end();
    return;
  }

  switch (req.url) {
    case "/upload":
      if (req.method.toLowerCase() === "post") upload(req, res);
      break;
    default:
      let link = (
        getProjectPath() +
        (req.url.length === 1 ? req.url + "index.html" : req.url)
      ).replace(/\//g, "\\");
      if (!fs.existsSync(link) || fs.statSync(link).isDirectory()) {
        console.log(link, "does not exist");
        res.end();
        return;
      }
      fs.readFile(link, (err, data) => {
        if (err) throw err;
        if (link.endsWith("html") || link.endsWith("htm")) {
          res.setHeader("Content-Type", "text/html");
        }
        res.end(data);
      });
      break;
  }
});
